package com.school.information.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.school.information.entity.SysMenuEntity;
import com.school.information.mapper.SysMenuMapper;
import com.school.information.service.SysMenuService;
import com.school.information.utils.UserUtil;
import com.school.information.vo.TreeSelectVO;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * (SysMenu)表服务实现类
 *
 * @author ycc
 * @since 2023-05-28 23:06:53
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenuEntity> implements SysMenuService {
    @Resource
    private SysMenuMapper menuMapper;

    @Override
    public Set<String> findMenuByUserId(Long userId) {
        Set<String> permsSet = new HashSet<String>();
        // 管理员拥有所有权限
        if (UserUtil.isAdmin(userId)) {
            permsSet.add("*:*:*");
        } else {
            List<SysMenuEntity> perms = menuMapper.findMenuByUserId(userId);
            for (SysMenuEntity perm : perms) {
                if (Objects.nonNull(perm)) {
                    permsSet.addAll(Arrays.asList(perm.getPerms().trim().split(",")));
                }
            }
        }
        return permsSet;
    }

    @Override
    public List<SysMenuEntity> selectMenuList(Long userId) {
        List<SysMenuEntity> menuList = null;
        // 管理员显示所有菜单信息
        if (UserUtil.isAdmin(userId)) {
            menuList = this.list();
        } else {
            menuList = menuMapper.selectMenuListByUserId(userId);
        }
        return menuList;
    }

    @Override
    public List<TreeSelectVO> buildMenuTreeSelect(List<SysMenuEntity> menus) {
        List<SysMenuEntity> menuTrees = buildMenuTree(menus);
        return menuTrees.stream().map(TreeSelectVO::new).collect(Collectors.toList());
    }

    /**
     * 构建前端所需要树结构
     *
     * @param menus 菜单列表
     * @return 树结构列表
     */
    private List<SysMenuEntity> buildMenuTree(List<SysMenuEntity> menus) {
        List<SysMenuEntity> returnList = new ArrayList<SysMenuEntity>();
        List<Long> tempList = new ArrayList<Long>();
        for (SysMenuEntity menu : menus) {
            tempList.add(menu.getId());
        }
        for (Iterator<SysMenuEntity> iterator = menus.iterator(); iterator.hasNext(); ) {
            SysMenuEntity menu = (SysMenuEntity) iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(menu.getParentId())) {
                recursionFn(menus, menu);
                returnList.add(menu);
            }
        }
        if (returnList.isEmpty()) {
            returnList = menus;
        }
        return returnList;
    }

    /**
     * 递归列表
     *
     * @param list
     * @param t
     */
    private void recursionFn(List<SysMenuEntity> list, SysMenuEntity t) {
        // 得到子节点列表
        List<SysMenuEntity> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysMenuEntity tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<SysMenuEntity> getChildList(List<SysMenuEntity> list, SysMenuEntity t) {
        List<SysMenuEntity> tlist = new ArrayList<SysMenuEntity>();
        Iterator<SysMenuEntity> it = list.iterator();
        while (it.hasNext()) {
            SysMenuEntity n = (SysMenuEntity) it.next();
            if (n.getParentId().equals(t.getId())) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SysMenuEntity> list, SysMenuEntity t) {
        return getChildList(list, t).size() > 0 ? true : false;
    }
}
